package myServer.handler;

import component.timeConsumingTask.ExecuteTaskCollector;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import myServer.session.ServerSession;
import protobuf.protoClass.ProtoMsg;

import java.util.concurrent.TimeUnit;

public class HeartBeatServerHandler extends IdleStateHandler {

    public static final int READ_IDLE_GAP = 150;

    public HeartBeatServerHandler() {
        /**
         * 第一个参数表示入站（Inbound）空闲时长，指的是一段时间内如果没有数据入站，就判定连接假死；
         * 第二个参数是出站（Outbound）空闲时长，指的是一段时间内如果没有数据出站，就判定连接假死；
         * 第三个参数是出/入站检测时长，表示在一段时间内如果没有出站或者入站，就判定连接假死；
         * 最后一个参数表示时间单位
         */
        super(READ_IDLE_GAP, 0, 0, TimeUnit.SECONDS);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //判断消息实例
        if (!(msg instanceof ProtoMsg.Message protoMessage)) {
            super.channelRead(ctx, msg);
            return;
        }
        //判断消息类型
        ProtoMsg.HeadType type = protoMessage.getType();
        if (type.equals(ProtoMsg.HeadType.HEART_BEAT)) {
            //异步处理,将心跳包,直接回复给客户端
            ExecuteTaskCollector.add(() -> {
                if (ctx.channel().isActive()) {
                    ctx.writeAndFlush(msg);
                }
            });
        }
        super.channelRead(ctx, msg);
    }

    @Override
    protected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception {
        System.out.println(READ_IDLE_GAP + "秒内未读到数据，关闭连接");
        ServerSession.closeChannelBySession(ctx);
    }

}
